package badugaclient;
/**
 * @author Wojtek N., Kamil M.
 * @version 0.7
 * Class which initiate client and control its movements.
 */
import java.io.IOException;
import java.net.UnknownHostException;

public class ClientSwitch  implements IObserver, IInformation
{
	public PlayerInfo p;
	public Gui gui;
	public GuiStart gs;
	private ClientServerCom com;
	
	/**
	 * Main constructor of the class. Connects player with the gui.
	 */
	ClientSwitch()
	{
		this.p = new PlayerInfo();
		this.com = new ClientServerCom();
		
		this.gs = new GuiStart(p);
		this.gui = new Gui(p);
		
		gs.addObserver(ClientSwitch.this);
		gui.addObserver(ClientSwitch.this);
		gs.setVisible(true);
	}
	
	/**
	 * Method in which, depending on income from server, different actions are taken.
	 * @param inFromServer an income from server
	 */
	public void messageReceived(String inFromServer)
	{
		try
		{
			com.getWhatIsMine((IInformation) this);
			p.setAction(com.checkAction(inFromServer));
			com.printClient("Got news for you: " + inFromServer);
			
			switch(p.getAction())
			{
				// Are you ready to start?
				case "RDY":
					
					if(inFromServer.substring(6,7).equals("?"))
					{
						
					  	//GUI.canWeStart();
						gs.LetsStartGame();
					}
					else
					{
						//pInfo.setInfo(com.display());
						
					}
					break;
				// Starting the game - have your cards in here.
				case "BEG":
					com.printClient(inFromServer);
					p.setHand(com.getMsgFromServer());
					com.printClient("Cards have come: "+p.getHandForView());
					gui.setHand();
					break;
				// Remember who have dealer button, big blind and small blind.
				case "DBS":
					com.printClient("Dealer, big blind, small blind holder as follows: "+inFromServer.substring(6));
					p.setDealerID(inFromServer.substring(6,7));
					p.setSmallID(inFromServer.substring(8, 9));
					p.setBigID(inFromServer.substring(10, 11));
					p.setCurrentTopBet(p.getBigBlind());
					if(p.getBigID().equals(p.getMyID()))
					{
						gui.displayPlayerBetAndBankroll();
					}
					else if(p.getSmallID().equals(p.getMyID()))
					{
						gui.displayPlayerBetAndBankroll();
					}
					gui.setDealer(p.getDealerID());
					gui.setBigBlind(p.getBigID());
					gui.setSmallBlind(p.getSmallID());
					//gs.setVisible(false);
					break;
				// Auction phase - here you can do an action or receive what others do.
				case "AUC":
					com.printClient("We are currently in " + inFromServer.substring(6, 7) + " round.");
					switch(inFromServer.substring(4,6))
					{
						// Welcome in x bet round!
						case "__":
							p.setBetRound(inFromServer.substring(6, 7));
							break;
						// Hey! Don't sleep, it's your turn. What will you do?
						case "ur":
							gui.auctionsButtonEnable();
							break;
						// Someone has played 'check'. Check if it was you. If yes, than change your data.
						case "ch":
							p.setPlayersID(inFromServer.substring(7));
							if(p.getMyID().equals(p.getPlayersID()))
							{
								com.printClient("Check.");
								gui.displayPlayerBetAndBankroll();
							}
							else
							{
								com.printClient("Player " + p.getPlayersID() + ": Check.");
							}
							break;
						// Someone has played 'bet'. Check if it was you. If yes, than change your data.
						case "be":
							p.setPlayersID(inFromServer.substring(7, 8));
							p.setPlayersBet(inFromServer.split("\\|")[1]);
							p.setPlayersTokens(inFromServer.split("\\|")[0].substring(8));
							p.setBetted(true);
							if(p.getSmallID().equals(p.getPlayersID()))
							{
								com.printClient("\n"+Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getSmallBlind())));
								p.setCurrentTopBet(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getSmallBlind())));
							}
							else if(p.getBigID().equals(p.getMyID()))
							{
								com.printClient("\n"+Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getBigBlind())));
								p.setCurrentTopBet(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getBigBlind())));
							}
							else
							{
								p.setCurrentTopBet(Integer.toString(p.getPlayersBet()));
							}
							gui.displayPlayerBetAndBankroll();
							com.printClient("Current max bet: " + p.getCurrentTopBet()+" in round "+p.getBetRound());
							if(p.getMyID().equals(p.getPlayersID()))
							{
								if(p.getSmallID().equals(p.getMyID()))
								{
									p.setMyBetInt(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getSmallBlind())));
								}
								else if(p.getBigID().equals(p.getMyID()))
								{
									p.setMyBetInt(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getBigBlind())));
								}
								else
								{
									p.setMyBetInt(Integer.toString(p.getMyBetInt()));
								}
								p.setMyTokens(Integer.parseInt(p.getPlayersTokens()));
								gui.displayPlayerBetAndBankroll();
								com.printClient("Bet.");
							}
							else
							{
								com.printClient("Player " + p.getPlayersID() + ": Bet.");
							}
							break;
						// Someone has played 'raise'. Check if it was you. If yes, than change your data.
						case "ra":
							p.setPlayersID(inFromServer.substring(7, 8));
							p.setPlayersBet(inFromServer.split("\\|")[1]);
							p.setPlayersTokens(inFromServer.split("\\|")[0].substring(8));
							p.setRaised(true);
							if(p.getSmallID().equals(p.getPlayersID()))
							{
								p.setCurrentTopBet(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getSmallBlind())));
							}
							else if(p.getBigID().equals(p.getMyID()))
							{
								p.setCurrentTopBet(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getBigBlind())));
							}
							else
							{
								p.setCurrentTopBet(Integer.toString(p.getPlayersBet()));
							}
							gui.displayPlayerBetAndBankroll();
							com.printClient("Current max bet: " + p.getCurrentTopBet()+" in round "+p.getBetRound());
							if (p.getMyID().equals(p.getPlayersID()))
							{
								if(p.getSmallID().equals(p.getMyID()))
								{
									p.setMyBetInt(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getSmallBlind())));
								}
								else if(p.getBigID().equals(p.getMyID()))
								{
									p.setMyBetInt(Integer.toString(p.getPlayersBet() + Integer.parseInt(p.getBigBlind())));
								}
								else
								{
									p.setMyBetInt(Integer.toString(p.getMyBetInt()));
								}
								p.setMyTokens(Integer.parseInt(p.getPlayersTokens()));
								gui.displayPlayerBetAndBankroll();
								com.printClient("Raise.");
							}
							else
							{
								com.printClient("Player " + p.getPlayersID() + ": Raise.");
							}
							break;
						// Someone has played 'call'. Check if it was you. If yes, than change your data.
						case "ca":
							p.setPlayersID(inFromServer.substring(7, 8));
							p.setPlayersBet(inFromServer.split("\\|")[1]);
							p.setPlayersTokens(inFromServer.split("\\|")[0].substring(8));
							gui.displayPlayerBetAndBankroll();
							if(p.getMyID().equals(p.getPlayersID()))
							{
								p.setMyBetInt(Integer.toString(p.getCurrentTopBet()));
								p.setMyTokens(Integer.parseInt(p.getPlayersTokens()));
								gui.displayPlayerBetAndBankroll();
								com.printClient("Call.");
							}
							else
							{
								com.printClient("Player " + p.getPlayersID() + ": Call.");
							}
							break;
						// Someone has played 'fold'. Check if it was you. If yes, than change your data.
						case "fo":
							p.setPlayersID(inFromServer.substring(7, 8));
							if(p.getMyID().equals(p.getPlayersID()))
							{
								gui.displayPlayerBetAndBankroll();
								com.printClient("Fold.");
							}
							else
							{
								com.printClient("Player " + p.getPlayersID() + ": Fold.");
							}
							break;
						// Someone has played 'all-in'. Check if it was you. If yes, than change your data.
						case "al":
							p.setPlayersID(inFromServer.substring(7, 8));
							p.setPlayersBet(inFromServer.substring(8));
							gui.displayPlayerBetAndBankroll();
							if(p.getMyID().equals(p.getPlayersID()))
							{
								p.setMyBetInt(Integer.toString(p.getPlayersBet() + p.getMyBetInt()));
								p.setMyTokens(0);
								gui.displayPlayerBetAndBankroll();
								com.printClient("All-In.");
							}
							else
							{
								com.printClient("Player " + p.getPlayersID() + ": All-In.");
							}
							break;
					}
					break;
				// It's time for changing cards phase.
				case "CHG":
					com.printClient("Card exchange phase.");
					switch(inFromServer.substring(4,6))
					{
						// It is not your turn. You should wait.
						case "__":
							com.printClient("Wait for your turn. Other players exchanging cards...");
							break;
						// OK, so it's your turn to exchange cards.
						case "os":
							gui.disableAll();
							gui.exchangeEnabled();
							com.printClient("Choose wisely, young padawan, which cards exchange you will...");
							break;
						// Here you go. Your new hand has come.
						case "cd":
							if(p.getMyID().equals(inFromServer.substring(6,7)))
							{
								p.setHand(inFromServer);
							}
							//com.printClient("Your current hand: "+p.getHandForView());
						// I'm just working here.
						default:
							p.setPlayersCardChange(inFromServer);
							gui.displayPlayerBetAndBankroll();
							gui.setHand();
							break;
					}
					break;
				// Oh, so we have a winner. Let's check who it is.
				case "WON":
					com.printClient("Ladies and gentleman, and the winner is...");
					switch(inFromServer.substring(4, 6))
					{
						// We'he got one winner! Good. If you are this one, change your data.
						case "on":
							p.setHowManyWinners(inFromServer.split("\\|")[0].substring(6));
							p.setWinnerID(inFromServer.split("\\|")[0].substring(6));
							p.setWinningAmount(inFromServer.split("\\|")[1]);
							if(p.getWinnerID().equals(p.getMyID()))
							{
								p.setMyTokensAfterAll(Integer.parseInt(p.getWinningAmount()));
							}
							else
							{
								p.setMyTokensAfterAll(0);
							}
							gui.disableAll();
							gui.winner();
							com.printClient("Player " + p.getWinnerID()+"! Congrats! You won " + p.getWinningAmount() + "tokens!");
							break;
						// We'he got a draw! Check if you are on the list of winners, maybe you have won something.
						case "dr":
							p.setHowManyWinners(inFromServer.split("\\|")[0].substring(6));
							p.setWinnersID(inFromServer.split("\\|")[0].substring(6));
							p.setWinningAmount(inFromServer.split("\\|")[1]);
							String sepWinnersID = "";
							for(int i=0; i<p.getHowManyWinners(); i++)
							{
								String temp = p.getWinnersID().substring(i, i+1);
								if(temp.equals(p.getMyID()))
								{
									p.setMyTokensAfterAll(Integer.parseInt(p.getWinningAmount()));
								}
								else
								{
									p.setMyTokensAfterAll(0);
								}
								sepWinnersID += temp + " ";
							}
							gui.disableAll();
							gui.winner();
							com.printClient("It was a draw between " +sepWinnersID+"! Each of them won " + p.getWinningAmount()+" tokens! Congrats!");
							break;	
					}
					break;
				// Asked if I want to continue.
				case "NXT":
					com.printClient("Do you wish to continue?");
					switch(inFromServer.substring(6, 8))
					{
						// Do I wish to continue?
						case "YN":
							gui.nextRound();
							break;
						// Damn, someone have lost... We need to start another table.
						case "PR":
							p.setLooserID(inFromServer.substring(8));
							break;
						// Game have ended. Don't worry, you will be transfered automaticlly to new table.
						case "ED":
							break;
					}
					break;
				case "ERR":
					com.printClient(inFromServer.substring(6));
					break;
			}
		}
		catch(IOException ioe)
		{
			ioe.printStackTrace();
		}
	}
	
	/**
	 * Updating starting frame (the one with host/port input).
	 */
	@Override
	public void updateGUI()
	{
		switch(p.getContent())
		{
			case "Connect":
				try
				{
					com.connect(p.getHost(), p.getConnectionPort());
					gs.changeToDisconnect();
					p.setAction(com.checkAction());
					com.getWhatIsMine((IInformation) this);
					if(p.getAction().equals("INI"))
					{
						p.setStartingParam(com.getMsgFromServer());
						com.printClient("Player ID: " +p.getMyID());
						
					}
					else if(p.getAction().equals("ERR"))
					{
						gs.changeToconnect();
					}
					com.display();				
				}
				catch(UnknownHostException uhe)
				{
					System.err.println("Cannot recognize host.");
					uhe.printStackTrace();
				}
				catch(IOException ioe)
				{
					System.err.println("I/O failed. Printing where the problem is.");
					ioe.printStackTrace();
				}
				catch(NullPointerException npe)
				{
					System.err.println("Don't try to read from something that, don't exists!");
					npe.printStackTrace();
				}
				break;
			case "Disconnect":
				try
				{
					p.setSentToServer(p.getMyID()+"DCN___");
					com.sendMessage(p.getSentToServer());
					com.stopListen();
					com.printClient("Disconnecting...");
					gs.changeToconnect();
					p.setInfo(com.disconnect());
					com.printClient("I'm outa' here...");
				}
				catch(IOException ioe)
				{
					System.err.println("I/O failed. Printing where the problem is.");
					ioe.printStackTrace();
				}
				break;
			case "Start game":
				com.sendMessage(p.getSentToServer());
				gs.setVisible(false);
				gui.setVisible(true);
				break;
		}
	}
	
	/**
	 * Updating main frame (the one in which game takes place).
	 */
	@Override
	public void updateGUIMain()
	{
		switch(p.getContent())
		{	
	
			case "Check":
				p.setSentToServer(p.getMyID()+"AUCch_");
				com.sendMessage(p.getSentToServer());
				com.printClient("Check. " + p.getSentToServer());
				gui.displayeAuctionButtons();
				break;
			case "Bet":
				p.setSentToServer(p.getMyID()+"AUCbe"+p.getMyBet());
				com.sendMessage(p.getSentToServer());
				com.printClient("Bet. " + p.getSentToServer());
				gui.displayeAuctionButtons();
				break;
			case "Raise":
				p.setSentToServer(p.getMyID()+"AUCra"+p.getMyRaise());
				com.sendMessage(p.getSentToServer());
				com.printClient("Raise. " + p.getSentToServer());
				gui.displayeAuctionButtons();
				break;
			case "Call":
				p.setSentToServer(p.getMyID()+"AUCca"+p.getCall());
				com.sendMessage(p.getSentToServer());
				com.printClient("Call. " + p.getSentToServer());
				gui.displayeAuctionButtons();
				break;
			case "Fold":
				p.setSentToServer(p.getMyID()+"AUCfo_");
				com.sendMessage(p.getSentToServer());
				com.printClient("Fold. " + p.getSentToServer());
				gui.displayeAuctionButtons();
				break;
			case "All-in":
				p.setSentToServer(p.getMyID()+"AUCal"+p.getMyTokens());
				com.sendMessage(p.getSentToServer());
				com.printClient("All-in. " + p.getSentToServer());
				gui.displayeAuctionButtons();
				break;
			case "Exchange":
				p.setSentToServer(p.getMyID()+"CHG__"+p.getCardsToChange());
				com.sendMessage(p.getSentToServer());
				com.printClient("Changing cards. " +p.getSentToServer());
				p.resetSelection();
				gui.exchangeDisable();
				break;
			case "Yes":
				p.defaultState();
				com.sendMessage(p.getMyID()+"NXT__Y");
				break;
			case "No":
				com.sendMessage(p.getMyID()+"NXT__N");
				com.stopListen();
				System.exit(0);
				break;
		}
	}
	
	
	@Override
	public void connectionException() 
	{
		System.err.println("Thread interrupted.");

	}

	@Override
	public void nullpointerException() 
	{
		System.err.println("Connection Failure - NullPointerException from Thread occured.");
	}
	
	
}
